package com.yangguang.service;

import com.alibaba.fastjson.JSONObject;
import com.yangguang.mapper.ImageFileMapper;
import com.yangguang.pojo.SmallTopic;
import com.yangguang.utils.FileUtil;
import com.yangguang.utils.ImageMerge;
import com.yangguang.utils.ImageShear;
import com.yangguang.utils.XunFeiUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ImageFileService {

    @Autowired
    private ImageFileMapper imageFileMapper;

    /**
     * 图片识别判分
     *
     * @return
     */
    public Map<Integer, Boolean> characterRecognition(MultipartFile file, String lastDir, String schoolid, String examid) {
        Map<Integer, Boolean> answerMap = new HashMap<>();
        try {
            //数据库查出的当前试卷给出的答题区域及答案
            //根据学校id跟考试id对数据库查询相应试卷记录的题目答案及坐标
            Map<String, Object> queryWrapper = new HashMap<>();
            queryWrapper.put("school_id", schoolid);
            queryWrapper.put("exam_id", examid);
            //试卷题目坐标及答案等参数
            List<SmallTopic> maps = imageFileMapper.selectByMap(queryWrapper);

            List<SmallTopic> smallTopicV = new ArrayList<>();
            List<SmallTopic> smallTopicH = new ArrayList<>();

            //裁剪方法书写位置
            //避免出现合并时第一个出现空指针
            InputStream inputStream = file.getInputStream();
            SmallTopic smallTopicInfo = maps.get(0);
            BufferedImage bufferedImageV = ImageShear.cutPicture(inputStream, lastDir, smallTopicInfo.getTopicX(),
                    smallTopicInfo.getTopicY(), smallTopicInfo.getWidth(), smallTopicInfo.getHeight());

            smallTopicV.add(maps.get(0));

            BufferedImage bufferedImageH = ImageShear.cutPicture(file.getInputStream(), lastDir, smallTopicInfo.getTopicX(),
                    smallTopicInfo.getTopicY(), smallTopicInfo.getWidth(), smallTopicInfo.getHeight());

            smallTopicH.add(maps.get(0));

            BufferedImage read = ImageIO.read(new File("C:\\Users\\yg\\Desktop\\tupian\\web_ocr\\src\\main\\resources\\templates\\分隔符￥.png"));

            read = resize(read, read.getWidth(), bufferedImageH.getHeight());

            bufferedImageV = ImageMerge.mergeImage(read, bufferedImageV, true);

            //从第二个开始
            for (int i = 1; i < maps.size(); i++) {
                InputStream imageinputStream = file.getInputStream();
                SmallTopic smallTopicForm = maps.get(i);
                //题目类型,0多选1单选2主观
                if (smallTopicForm.getType() == 0) {
                    smallTopicH.add(smallTopicForm);
                    bufferedImageH = ImageMerge.mergeImage(bufferedImageH, read, false);
                    bufferedImageH = cutAndSplice(imageinputStream, lastDir, smallTopicForm, bufferedImageH, false);

                } else if (smallTopicForm.getType() == 1) {
                    smallTopicV.add(smallTopicForm);
                    bufferedImageV = ImageMerge.mergeImage(bufferedImageV, read, true);
                    bufferedImageV = cutAndSplice(imageinputStream, lastDir, smallTopicForm, bufferedImageV, true);
                }

            }
            bufferedImageV = ImageMerge.mergeImage(bufferedImageV, read, true);
            //bufferedImageV = test(bufferedImageV);

            ImageIO.write(bufferedImageV, lastDir, new File("C:\\Users\\yg\\Desktop\\tupian\\web_ocr\\src\\main\\resources\\static\\test2.jpg"));


            //
            if (smallTopicV.size() > 1) {
                String base64Image = FileUtil.bufferedImageToBase64Image(bufferedImageV, lastDir);
                List<Map<String, Object>> line = xunFeiOcrResponseJsonToString(base64Image);
                String characters = "";
                for (Map<String, Object> map : line) {
                    StringBuffer answer = new StringBuffer();
                    List<Map<String, String>> word = (List<Map<String, String>>) map.get("word");
                    for (Map<String, String> wordInfo : word) {
                        String content = wordInfo.get("content");
                        answer.append(content);
                    }
                    //所选与数据库正确的进行比对

                    characters += extractCharacter(answer.toString());
                }

                for (int i = 0; i < smallTopicV.size() - 1; i++) {

                    SmallTopic smallTopic = smallTopicV.get(i);
                    answerMap.put(smallTopic.getTopicCode(), String.valueOf(characters.charAt(i)).equalsIgnoreCase(smallTopic.getAnswer()));
                }
            } else if (smallTopicH.size() > 1) {
                String base64Image = FileUtil.bufferedImageToBase64Image(bufferedImageH, lastDir);
                List<Map<String, Object>> line = xunFeiOcrResponseJsonToString(base64Image);
                //遍历集合判断答案
                for (int i = 0; i < smallTopicH.size(); i++) {
                    Map<String, Object> map = line.get(i);
                    StringBuffer answer = new StringBuffer();
                    List<Map<String, String>> word = (List<Map<String, String>>) map.get("word");
                    for (Map<String, String> wordInfo : word) {
                        String content = wordInfo.get("content");
                        answer.append(content);
                    }
                    //所选与数据库正确的进行比对
                    String characters = extractCharacter(answer.toString());
                    SmallTopic smallTopic = smallTopicH.get(i);
                    answerMap.put(smallTopic.getTopicCode(), characters.equalsIgnoreCase(smallTopic.getAnswer()));

                }


            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return answerMap;//FileUtil.bufferedImageToBase64Image(image);
    }


    public void addTemplate(SmallTopic smallTopic) {
        imageFileMapper.insert(smallTopic);
    }


    public static List<Map<String, Object>> xunFeiOcrResponseJsonToString(String base64Image) throws UnsupportedEncodingException {
        //讯飞响应
        Map<String, Object> ocrResponse = XunFeiUtil.httpOcrRequest(base64Image);

        System.out.println(JSONObject.toJSONString(ocrResponse));

        //有用数据
        Map<String, List<Object>> data = (Map<String, List<Object>>) ocrResponse.get("data");
        //真实数据
        List<Object> block = data.get("block");
        Map<String, Object> blockMap = (Map<String, Object>) block.get(0);
        List<Map<String, Object>> line = (List<Map<String, Object>>) blockMap.get("line");


        return line;
    }

    /**
     * 使用循环提取字符，判断字符是否在A-Z 、a-z区间
     *
     * @param st
     */
    public static String extractCharacter(String st) {
        String extractStr = "";
        for (int i = 0; i < st.length(); i++) {
            char charAt = st.charAt(i);
            if ((charAt <= 'Z' && charAt >= 'A') || charAt == '@') {
                extractStr += charAt;
            } else if ((charAt <= 'z' && charAt >= 'a') || charAt == '@') {
                extractStr += charAt;
            }
        }
        return extractStr;
    }


    /**
     * 剪切并拼接
     */

    public static BufferedImage cutAndSplice(InputStream inputStream, String lastDir, SmallTopic smallTopic, BufferedImage bufferedImage, boolean vOrH) {
        BufferedImage image = ImageShear.cutPicture(inputStream, lastDir, smallTopic.getTopicX(),
                smallTopic.getTopicY(), smallTopic.getWidth(), smallTopic.getHeight());
        System.out.println(image.getWidth() + "++++++" + image.getHeight());
        bufferedImage = ImageMerge.mergeImage(bufferedImage, image, vOrH);
        return bufferedImage;
    }

    //调整图片大小
    public static BufferedImage resize(BufferedImage img, int newW, int newH) {
        int w = img.getWidth();
        int h = img.getHeight();
        BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
        Graphics2D g = dimg.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
        g.dispose();
        return dimg;
    }


    /*//图片二值化
    public BufferedImage test(BufferedImage bi) {
        //BufferedImage bi=ImageIO.read(new File("D:/Test/binary/test.jpg"));//通过imageio将图像载入
        int h = bi.getHeight();//获取图像的高
        int w = bi.getWidth();//获取图像的宽
        int rgb = bi.getRGB(0, 0);//获取指定坐标的ARGB的像素值
        int[][] gray = new int[w][h];
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                gray[x][y] = getGray(bi.getRGB(x, y));
            }
        }

        BufferedImage nbi = new BufferedImage(w, h, BufferedImage.TYPE_BYTE_BINARY);
        int SW = 160;
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                if (getAverageColor(gray, x, y, w, h) > SW) {
                    int max = new Color(255, 255, 255).getRGB();
                    nbi.setRGB(x, y, max);
                } else {
                    int min = new Color(0, 0, 0).getRGB();
                    nbi.setRGB(x, y, min);
                }
            }
        }

        return nbi;
        //ImageIO.write(nbi, "jpg", new File("D:/Test/binary/二值化后_无压缩.jpg"));
    }

    public static int getGray(int rgb) {
        String str = Integer.toHexString(rgb);
        int r = Integer.parseInt(str.substring(2, 4), 16);
        int g = Integer.parseInt(str.substring(4, 6), 16);
        int b = Integer.parseInt(str.substring(6, 8), 16);
        //or 直接new个color对象
        Color c = new Color(rgb);
        r = c.getRed();
        g = c.getGreen();
        b = c.getBlue();
        int top = (r + g + b) / 3;
        return (int) (top);
    }

    *//**
     * 自己加周围8个灰度值再除以9，算出其相对灰度值
     *
     * @param gray
     * @param x
     * @param y
     * @param w
     * @param h
     * @return
     *//*
    public static int getAverageColor(int[][] gray, int x, int y, int w, int h) {
        int rs = gray[x][y]
                + (x == 0 ? 255 : gray[x - 1][y])
                + (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1])
                + (x == 0 || y == h - 1 ? 255 : gray[x - 1][y + 1])
                + (y == 0 ? 255 : gray[x][y - 1])
                + (y == h - 1 ? 255 : gray[x][y + 1])
                + (x == w - 1 ? 255 : gray[x + 1][y])
                + (x == w - 1 || y == 0 ? 255 : gray[x + 1][y - 1])
                + (x == w - 1 || y == h - 1 ? 255 : gray[x + 1][y + 1]);
        return rs / 9;
    }*/

}
